package com.sitech.ibnms.c3p.task;

import com.sitech.ibnms.c3p.service.DistributeLock;
import com.sitech.ismp.workflow.domain.Task;
import com.sitech.ismp.workflow.outside.impl.SynWorkflowService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.List;
import java.util.concurrent.locks.Lock;

import static com.sitech.ibnms.c3p.Application.sneakyThrow;

/**
 * Created by liujhc on 11/12.
 */
@Component
public class WorkflowService {
    @Autowired
    private SynWorkflowService workflowService;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private DistributeLock distributeLock;

    public Task startProcess(int processId, String user, String title, String processDeadline, String taskDeadline, String wf_num, int parentSerialNo, int parentTaskId) {
        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            Task task = workflowService.startProcess(processId, user, StringUtils.substring(title, 0, 500), processDeadline, taskDeadline, wf_num, parentSerialNo, parentTaskId);
            transactionManager.commit(transaction);
            return task;
        } catch (Exception e) {
            transactionManager.rollback(transaction);
            throw sneakyThrow(e);
        }
    }

    public List<Task> submitTask(int taskId, String user, String title, String taskDeadline, int serialNo) {
        Lock lock = distributeLock.newLock(serialNo);
        TransactionStatus transaction = null;
        try {
            lock.lock();
            transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
            List<Task> tasks = workflowService.submitTask(taskId, user, StringUtils.substring(title, 0, 500), taskDeadline, serialNo);
            transactionManager.commit(transaction);
            return tasks;
        } catch (Exception e) {
            transactionManager.rollback(transaction);
            throw sneakyThrow(e);
        } finally {
            lock.unlock();
        }
    }

    public void terminate(int serialNo, String user, String desc) {
        Lock lock = distributeLock.newLock(serialNo);
        TransactionStatus transaction = null;
        try {
            lock.lock();
            transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
            workflowService.terminate(serialNo, user, StringUtils.substring(desc, 0, 500));
            transactionManager.commit(transaction);
        } catch (Exception e) {
            transactionManager.rollback(transaction);
            throw sneakyThrow(e);
        } finally {
            lock.unlock();
        }
    }
}
